package com.pzl.surfaceview.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * Created by zl.peng on 2016-03-11.
 * 线程死循环，数据处理+绘制数据：可以阻塞自己看起来自己卡，但阻塞不了UI线程的其它组件绘制，如果自己看起来卡但至少不会ANR
 * 注意：每次利用SurfaceHolder获得画布时，前一次的内容将会保留。
 * 双缓冲造成的屏幕闪烁问题
 * 同步
 * 多线程绘制
 */
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "MySurfaceView";
    private SurfaceHolder mSurfaceHolder;
    private MyThread mMyThread;
    private Paint mPaint;
    private int mCenterX;
    private int mCenterY;
    private int mColor = Color.WHITE;
    private boolean mDraw = false;
    private Bitmap board = null;
    private Canvas boardCanvas = null;
    /**
     * 刷新频率
     */
    private int mfrequency;

    public MySurfaceView(Context context) {
        this(context, null);
    }

    public MySurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        mSurfaceHolder = getHolder();
        mSurfaceHolder.addCallback(this);
        mMyThread = new MyThread(mSurfaceHolder);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.STROKE);
    }

    public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mMyThread.mRun = true;
        mMyThread.start();
        mCenterX = 0;
        mCenterY = 0;
        board = Bitmap.createBitmap(this.getWidth(), this.getHeight(),
                Bitmap.Config.ARGB_8888);
        boardCanvas = new Canvas(board);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mMyThread.mRun = false;
    }

    class MyThread extends Thread {
        private SurfaceHolder mSurfaceHolder;
        public boolean mRun = false;
        private int mR = 0;
        private int mStep = 2;
        private int mMost = 200;


        public MyThread(SurfaceHolder holder) {
            mSurfaceHolder = holder;
        }


        @Override
        public void run() {
            while (mRun) {
                logic();
                Canvas canvas = null;
                synchronized (mSurfaceHolder) {
                    try {
                        if (mDraw) {
                            canvas = mSurfaceHolder.lockCanvas();
                            //boardCanvas.drawColor(Color.BLACK);//clear canvas;画布清除历史，只记录当前绘制
                            boardCanvas.drawCircle(mCenterX, mCenterY, mR, mPaint);//2画布缓存都同一到此bitmap中来，保留所有历史记录，防止闪烁
                            if (canvas != null && board != null) {
                                canvas.drawBitmap(board, 0, 0, null);
                            }
                            //频率
                            Thread.sleep(10);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (canvas != null) {
                            mSurfaceHolder.unlockCanvasAndPost(canvas);
                        }
                    }
                }

            }
        }

        private void logic() {
            mR += mStep;
            if (mR >= mMost) {
                mR = 0;
            }
        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mCenterX = (int) event.getX();
                mCenterY = (int) event.getY();
                mDraw = true;
                break;
            case MotionEvent.ACTION_MOVE:
                mCenterX = (int) event.getX();
                mCenterY = (int) event.getY();
                mDraw = true;
                break;
            case MotionEvent.ACTION_UP:
                mDraw = false;
                break;
        }
        return true;
    }
}
